A hardware intrinsic represents an instruction or set of instructions that is natively supported and implemented by a given Central Processing Unit (CPU) or other type of computer processor. In most cases, the architecture of a given CPU includes an instruction set which identifies the base operations that the CPU is able to perform. These operations range from fairly simple, such as an add instruction which adds the values within two input registers and outputs the result to an output register, to very complex operations, such as performing encryption under one or more cryptographic schemes and vector operations. However, the machine code needed to access said operations tends to be painstakingly difficult to program directly. Thus, most programmers use “high-level” programming languages, such as C++, Java, Ruby, and so forth which are designed to be more “human readable” and which rely on compilers and/or interpreters to transform the program instructions written for a higher-level language into the machine instructions that can actually be executed by the underlying hardware. In some cases, multiple levels of compilers and/or interpreters are used, such as the case with the Java operating environment.
The Java operating environment generally comprises at least two tiers of transformation. The first tier is the use of a source compiler to convert Java source code into an intermediate language referred to as “byte code”. The second tier uses a Java Virtual Machine (JVM) to convert the “byte code” into machine instructions that can execute on the underlying hardware via a Just-in-Time (JIT) compiler, an interpreter, or a combination of both. The multi-tiered approach taken by Java allows programmers of Java source code to write code that is the same across all platforms without worrying about the underlying hardware. As a result, the work needed to ensure cross compatibility between platforms is drastically reduced, allowing Java programs to be developed in a safe and efficient manner. Instead, the task of ensuring cross-compatibility is placed on the JVM, which is responsible for determining the capabilities of the underlying hardware and converting the bytecode instructions into machine instructions that can actually execute on the underlying hardware.
One issue that the developers of virtual machines, such as the JVM, encounter is how to introduce new hardware intrinsics into the virtual machine operating environment. As technology progresses, the instruction set supported by CPUs continues to expand. For instance, CPU manufacturers may identify certain sets of instructions which are typically executed together and instead choose to implement a new instruction in the hardware of the CPU that can achieve the same effect with fewer clock cycles. However, once a new hardware intrinsic becomes available on a CPU, the developers of the virtual machine have to perform many infrastructure changes, oftentimes manually, in order to utilize the new functionality. This is further compounded by the fact that CPU manufacturers do not always standardize functionality or the manner in which the functionality should be used. Thus, different CPUs may provide different sets of functionality and/or may adhere to completely different calling conventions and/or Application Binary Interfaces (ABIs). Thus, in addition to introducing the new functionality into the virtual machine operating environment, the developers also have to program multiple implementations corresponding to the different hardware environments, often also including an implementation for hardware that does not natively support the new functionality.
Presently, importing a new hardware intrinsic requires a long jagged cut through multiple layers of both the source language and the virtual machine operating environment. Using Java as an example, the steps currently followed to import a new hardware intrinsic include surfacing the intrinsic in the Java language (often through a Java method), organizing the definition of the method to mark the method as an a specific intrinsic, modifying the JVM to recognize the mark, and in response to detecting the mark perform special processing for the specified type of intrinsic. The special processing often includes tasks such as defining how data should be passed to the hardware intrinsic (such as which registers to populate before execution and which registers to extract the result from), checks to determine whether the underlying hardware supports the intrinsic, and selection of machine code to execute which emits the instruction based on the capabilities of the underlying hardware. In order to effect such changes, developers of the JVM often have to manually modify many different points within the Java language and the JVM in order to utilize to utilize the new hardware intrinsic. Although a JVM is used in the above example, the issue presented above is applicable to many different virtual machine designs. Thus, a design architecture for a virtual machine that minimizes the number of points that need to be modified, especially within the design of the virtual machine itself as opposed to the source language, would allow new hardware intrinsics to be added in a more expedient and efficient manner.